﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Text;
using System.Threading;
//using System.Web;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Phone.Net.NetworkInformation;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Events;
using WeiboPlus.Models;
using WeiboPlus.Service;
using WeiboPlus.Service.Event;
using WeiboPlus.Shell.ViewModel;
//using WeiboPlus.Sina;
using WeiboPlus.Common;
using GalaSoft.MvvmLight.Messaging;
using WeiboPlus.Shell.Events;
using WeiboPlus.ViewModel;
using System.Xml.Linq;
using WeiboPlus.Shell.Model;

namespace WeiboPlus.Shell.ViewModel
{
    public class MainViewModel : CollectionVMBase<CardViewModel>
    {
        #region Field
        //SNSCounts _counts;
        object _countsObj = new object();
        //SNSPagingInfo _pagingInfo;
        //int pagecount = 10;
        //int _page = 0;
        //ISNSPollingService _pollingSvc;
        IStatusService _statusSvc;
        private IEventAggregator _ev;
        #endregion

        #region Property
        string userName;

        public string UserName
        {
            get { return userName; }
            set { userName = value; RaisePropertyChanged("UserName"); }
        }

        public ApplicationSetting AppSetting
        {
            get { return PhoneApplicationController.Current.AppSetting; }
        }

        private string countInfoText;

        public string CountInfoText
        {
            get
            {
                return countInfoText;
            }
            set
            {
                if (value == countInfoText)
                    return;
                countInfoText = value;
                RaisePropertyChanged("CountInfoText");
            }
        }

        private ObservableCollection<SNSAccount> bindedAccounts;

        public ObservableCollection<SNSAccount> BindedAccounts
        {
            get { return bindedAccounts; }
            set
            {
                bindedAccounts = value;
                RaisePropertyChanged(() => BindedAccounts);
            }
        }

        string statusToUpdate;

        public string StatusToUpdate
        {
            get { return statusToUpdate; }
            set
            {
                statusToUpdate = value;
                RaisePropertyChanged(() => StatusToUpdate);
            }
        }

        BitmapImage imageToSend;

        public BitmapImage ImageToSend
        {
            get { return imageToSend; }
            set
            {
                imageToSend = value;
                RaisePropertyChanged(() => ImageToSend);
            }
        }

        int pivotSelectedIndex;

        public int PivotSelectedIndex
        {
            get
            {
                return pivotSelectedIndex;
            }
            set
            {
                pivotSelectedIndex = value;
                RaisePropertyChanged("PivotSelectedIndex");
                ExecuteOnUIThread(() =>
                {
                    PerformGetItems();
                });

            }
        }

        private CardViewModel selectedItem;

        public CardViewModel SelectedItem
        {
            get { return selectedItem; }
            set
            {
                selectedItem = value;
                RaisePropertyChanged(() => SelectedItem);
            }
        }

        public ObservableCollection<SNSProvider> SupportedProviders
        {
            get
            {
                var providers = SNSProviderManager.Current.GetAllSupportedProviders().ToObservableCollection();
                //if (providers.Count > 0)
                //    SelectedProvider = providers.Where((sp)=>sp.Type== SNSProviderType.Sina).FirstOrDefault();
                return providers;
            }
        }

        private SNSProvider selectedProvider;

        public SNSProvider SelectedProvider
        {
            get
            {
                return selectedProvider;
            }
            set
            {
                selectedProvider = value;
                RaisePropertyChanged(() => SelectedProvider);
            }
        }
        #endregion

        #region Command

        public DelegateCommand Authorize { get; set; }
        public DelegateCommand ClearPhoto { get; set; }
        public DelegateCommand Send { get; set; }
        public DelegateCommand ClearSearch { get; set; }

        #endregion

        public MainViewModel()
        {
            CheckNetworkConnectivity();
            _ev = PhoneApplicationController.Current.Container.Resolve<IEventAggregator>();
            HasBindedAccount = AccountManager.Current.GetAllAccount().Any(a => a.IsBind == true);

            if (HasBindedAccount)
            {
                var user = AccountManager.Current.GetAllAccount().First();
                if (user.UserLite != null)
                    UserName = user.UserLite.Name;
            }

            Authorize = new DelegateCommand(AuthorizeMethod, () => { return !Loading; });

            PropertyChanged += new PropertyChangedEventHandler(MainViewModel_PropertyChanged);

            Send = new DelegateCommand(SendMethod, () => { return !Loading; });
        }

        void MainViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Loading")
            {
                Authorize.RaiseCanExecuteChanged();
            }
        }

        private void CheckNetworkConnectivity()
        {
            Timer t = new Timer((status) =>
            {
                var isAva = NetworkInterface.GetIsNetworkAvailable();

                ExecuteOnUIThread(
                    () =>
                    {
                        IsNetworkAvailable = isAva;

                        //if (!IsNetworkAvailable)
                        //    MessageBox.Show(AppResx.NoConnection);
                    });
            }, null, 0, 6000);
        }

        /// <summary>
        /// Creates and adds a few ItemViewModel objects into the Items collection.
        /// </summary>
        protected override void LoadData()
        {
            if (!HasBindedAccount || Items.Count > 0)
            {
                return;
            }
            XDocument document = XDocument.Load("data.xml");

            ThreadPool.QueueUserWorkItem((d) =>
            {
                var doc = d as XDocument;
                if (doc != null && doc.FirstNode != null)
                {
                    var cards = from c in doc.Root.Elements("Card")
                                select new Card
                                {
                                    Id = int.Parse(c.Attribute("Id").Value),
                                    Imagesource = CardViewModel.IMAGE_FOLDER + c.Attribute("ImageSource").Value,
                                    Title = c.Attribute("Title").Value,
                                    SubTitle = c.Attribute("SubTitle").Value,
                                    Positive = c.Element("Reading").Attribute("Positive").Value,
                                    Opposite = c.Element("Reading").Attribute("Opposite").Value
                                };
                    PopupItems(Items, cards);
                }
            }, document);
        }

        public Card GetCard(int index)
        {
            try
            {
                XDocument doc = XDocument.Load("data.xml");

                var card = (from c in doc.Root.Elements("Card")
                            select new Card
                            {
                                Id = int.Parse(c.Attribute("Id").Value),
                                Imagesource = CardViewModel.IMAGE_FOLDER + c.Attribute("ImageSource").Value,
                                Title = c.Attribute("Title").Value,
                                SubTitle = c.Attribute("SubTitle").Value,
                                Positive = c.Element("Reading").Attribute("Positive").Value,
                                Opposite = c.Element("Reading").Attribute("Opposite").Value
                            }).Skip(index).FirstOrDefault();
                return card;
            }
            catch (Exception error)
            {
                return null;
            }
        }

        private bool isNetworkAvailable;

        public bool IsNetworkAvailable
        {
            get { return isNetworkAvailable; }
            set
            {
                if (IsNetworkAvailable != value)
                {
                    isNetworkAvailable = value;
                    RaisePropertyChanged(() => IsNetworkAvailable);
                }
            }
        }

        private bool hasBindedAccount;

        public bool HasBindedAccount
        {
            get
            {
                return hasBindedAccount;
            }
            set
            {
                hasBindedAccount = value;
                RaisePropertyChanged(() => HasBindedAccount);
            }
        }

        protected override void Initialize()
        {
            _statusSvc = PhoneApplicationController.Current.Container.Resolve<IStatusService>();
        }

        private void AuthorizeMethod()
        {
            Loading = true;
            Authorize.RaiseCanExecuteChanged();

            SNSProviderType t = SNSProviderType.Sina;
            //if (SelectedProvider == null || SelectedProvider.Type == SNSProviderType.Unknow)
            //{
            //    t = SNSProviderType.Sina;
            //}
            //else
            //{
            //    t = SelectedProvider.Type;
            //}

            AuthorizeHelper.NewRequestToken(t, (account, result) =>
            {
                ExecuteOnUIThread(() =>
                       {
                           if (!result.IsSuccess)
                               MessageBox.Show(result.Message);
                           else
                           {
                               Loading = false;
                               PhoneApplicationController.Current.Container.Resolve<IEventAggregator>().GetEvent<NavigationRequestEvent>().Publish(new NavigationContext() { Destination = new Uri("/Views/AuthPage.xaml", UriKind.RelativeOrAbsolute), SimpleParameter = account.AccountID });
                           }
                       });
            });
        }

        private void PerformGetItems()
        {
            switch (PivotSelectedIndex)
            {
                case 0:
                    LoadData();
                    break;
                //case 1:
                //    GetMentions();
                //    break;
                //case 2:
                //    GetCommentsToMe();
                //    break;
                //case 3:
                //    GetCommentsByMe();
                //    break;
                default:
                    break;
            }
        }

        private void ClearPhotoMethod()
        {
            ImageToSend = null;
        }

        private void SendMethod()
        {
            if (string.IsNullOrEmpty(StatusToUpdate))
                return;
            //var text = Helper.GetUrlEncodeStr(StatusToUpdate);
            Loading = true;
            SNSRequest request;
            if (ImageToSend == null)
            {
                request = new SNSRequest() { Type = SNSType.AddStatus, WebMethod = Hammock.Web.WebMethod.Post };
                request.Parameters.Add(new SNSParameter(SNSParametersConstants.STATUS_TEXT, StatusToUpdate));
            }
            else
            {
                byte[] data;
                using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (file.FileExists("testfile.jpeg"))
                        file.DeleteFile("testfile.jpeg");

                    using (IsolatedStorageFileStream fileStream = file.OpenFile("testfile.jpeg", FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        // Get an Image Stream
                        using (MemoryStream ms = new MemoryStream())
                        {
                            WriteableBitmap btmMap = new WriteableBitmap(ImageToSend);

                            // write an image into the stream
                            System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms,
                                ImageToSend.PixelWidth, ImageToSend.PixelHeight, 0, AppSetting.UploadImageResolution.Quality);

                            // reset the stream pointer to the beginning
                            ms.Seek(0, 0);
                            //read the stream into a byte array
                            data = new byte[ms.Length];
                            ms.Read(data, 0, data.Length);
                        }
                        fileStream.Write(data, 0, data.Length);
                        fileStream.Close();
                    }
                }

                request = new SNSRequest() { Type = SNSType.Upload, WebMethod = Hammock.Web.WebMethod.Post };

                //FOR TENCENT
                request.Parameters.Add(new SNSFileParameter(SNSParametersConstants.PIC, "testfile.jpeg", data) { Style = ParameterStyle.FilePath });

                //FOR RENREN
                request.Parameters.Add(new SNSFileParameter(SNSParametersConstants.UPLOAD, "testfile.jpeg", data) { Style = ParameterStyle.FilePath });
                request.Parameters.Add(new SNSParameter(SNSParametersConstants.CAPTION, StatusToUpdate) { Style = ParameterStyle.Post });

                request.Parameters.Add(new SNSParameter(SNSParametersConstants.STATUS_TEXT, Uri.EscapeDataString(StatusToUpdate)) { Style = ParameterStyle.Post });

            }

            request.Parameters.Add(new SNSParameter(SNSParametersConstants.CONTENT, StatusToUpdate));
            request.Parameters.Add(new SNSParameter(SNSParametersConstants.CLIENT_IP, "127.0.0.1"));

            _statusSvc.UpdateStatus(request, (data, result) =>
            {
                ExecuteOnUIThread(() =>
                {
                    if (!result.IsSuccess)
                    {
                        ExecuteOnUIThread(() => { MessageBox.Show(result.Message); Loading = false; });

                        return;
                    }
                    else
                    {
                        //PopupItems(Items, new List<SNSStatus>() { data }, true);
                        //Debug.WriteLine("{0}: {1}", DateTime.Now.ToLongTimeString(), data.Text);
                        //PivotSelectedIndex = 0;
                        //RefreshTimeLine("home");
                        //if (ImageToSend != null)
                        //    ImageToSend = null;
                    }

                    Loading = false;
                    //ClearStatusToSend();
                });

            });
        }

        private void ClearStatusToSend()
        {
            StatusToUpdate = string.Empty;
            ImageToSend = null;
            //throw new NotImplementedException();
        }

        protected void PopupItems<T1, T2>(ObservableCollection<T1> items, IEnumerable<T2> data)
            where T1 : ViewModelBase<T2>, new()
        {
            var r = new Random(100);

            foreach (var d in data)
            {
                ExecuteOnUIThread(
                    new Action<T2>(
                        (card) =>
                        {
                            var viewmodel = new T1
                            {
                                Item = card
                            };
                            int index = 0;
                            if (items.Count > 1)
                                index = r.Next(items.Count);
                            items.Insert(index, viewmodel);
                        })
                , d);

                Thread.Sleep(200);
            }

            Thread.Sleep(200);
            ExecuteOnUIThread(() =>
            {
                Loading = false;
            });
        }


        public void Load()
        {
            LoadData();
            //throw new NotImplementedException();
        }
    }
}
